/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package simple.utils.pool;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.Closeable;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * Generic pool for reusable objects.<br/>
 * This class is thread safe!<br/>
 *
 * @author rehak
 */
public abstract class Pool<E> implements Closeable {

    private static final Logger LOGGER = LoggerFactory.getLogger(Pool.class);
    private LinkedBlockingQueue<E> queue = new LinkedBlockingQueue<E>();

    public Pool() {
    }

    /**
     * This method is called from returnInstance
     *
     * @param instance
     */
    protected void cleanUp(E instance) {
    }

    /**
     * Destroys instance - called from close()
     *
     * @param instance
     */
    protected void destroy(E instance) {
    }

    @Override
    public void close() {
        E e;
        while ((e = queue.poll()) != null) {
            destroy(e);
        }
    }

    public E getInstance() {
        E poll = queue.poll();
        if (poll == null) {
            return createInstance();
        } else {
            return poll;
        }
    }

    protected abstract E createInstance();

    public void returnInstance(E instance) {
        cleanUp(instance);
        queue.add(instance);
    }
}
